﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework;

namespace client.app
{
    public abstract class LayerImage : comm.world.BObject, world.IBObject
    {
        public string LayerName { get; private set; }
        public bool Display { get { return _display; } set { _display = value; } }
        public bool IsRemove { get; private set; }
        public float DisplayX { get; set; }
        public float DisplayY { get; set; }
        public int Width { get; protected set; }
        public int Height { get; protected set; }

        bool _display = true;

        public LayerImage(string layerName)
        {
            LayerName = layerName;
        }

        public void Remove()
        {
            IsRemove = true;
            System.Console.WriteLine("remove");
        }

        public virtual void BeginDraw(comm.TimeStat timeStat)
        {
        }
        public virtual void Draw(comm.TimeStat timeStat)
        {
        }
    }

    public sealed class LayerManager : comm.world.BObject, world.IBObject
    {
        Dictionary<string, List<LayerImage>> _imageDic = new Dictionary<string, List<LayerImage>>();
        List<string> _layerList = new List<string>();
        List<RSprite> _rSpriteList = new List<RSprite>();
        LayerImage[] _draws = null;

        public LayerManager(string[] layers)
        {
            _layerList.AddRange(layers);
            foreach (var layer in _layerList)
            {
                _imageDic.Add(layer, new List<LayerImage>());
            }
        }

        List<LayerImage> GetImageList(string layer)
        {
            List<LayerImage> obj;
            _imageDic.TryGetValue(layer, out obj);
            return obj;
        }

        public void AddImage(LayerImage image)
        {
            lock (_imageDic)
            {
                if (!_imageDic.ContainsKey(image.LayerName))
                {
                    _layerList.Add(image.LayerName);
                    _imageDic.Add(image.LayerName, new List<LayerImage>());
                }
                GetImageList(image.LayerName).Add(image);
            }
        }
        public void ClearImage()
        {
            var layers = _layerList.ToArray();
            foreach (var layer in layers)
            {
                GetImageList(layer).Clear();
            }
        }

        public void AddRSprite(RSprite rSprite)
        {
            _rSpriteList.Add(rSprite);
        }
        public void RemoveRSprite(RSprite rSprite)
        {
            _rSpriteList.Remove(rSprite);
        }
        public void ClearRSprite()
        {
            _rSpriteList.Clear();
        }

        public void Clear()
        {
            ClearRSprite();
            ClearImage();
        }

        protected override void OnUpdate(comm.TimeStat timeStat)
        {
            var rSprites = _rSpriteList.ToArray();
            foreach (var rSprite in rSprites)
            {
                rSprite.Update(timeStat);
            }

            List<LayerImage> drawList = new List<LayerImage>();
            var layers = _layerList.ToArray();
            foreach (var layer in layers)
            {
                var imageList = GetImageList(layer);
                var newImageList = new List<LayerImage>();
                foreach (var image in imageList)
                {
                    if (!image.IsRemove)
                    {
                        image.Update(timeStat);
                        drawList.Add(image);
                        newImageList.Add(image);
                    }
                }
                imageList.Clear();
                imageList.AddRange(newImageList);
            }
            _draws = drawList.ToArray();
        }

        public void BeginDraw(comm.TimeStat timeStat)
        {
            var draws = _draws;
            if (draws != null)
            {
                foreach (var image in draws)
                {
                    image.BeginDraw(timeStat);
                }
            }
        }
        public void Draw(comm.TimeStat timeStat)
        {
            var draws = _draws;
            if (draws != null)
            {
                foreach (var image in draws)
                {
                    image.Draw(timeStat);
                }
            }
        }
    }
}
